﻿using System;
using System.Globalization;
using System.IO;
using System.Reflection;

namespace SessionHunter
{
    /// <summary>
    /// This is an entry point that allows us to have a single exe for all of the assemblies.  
    /// To add an assembly:
    /// -Add a reference.  Make sure to leave Copy Local to true
    /// -Add it to the assemblies folder as a link to the assembly in the libs folder
    /// -Change the Build Action to Embedded Resource
    /// </summary>
    /// <remarks>
    /// See http://www.digitallycreated.net/Blog/61/combining-multiple-assemblies-into-a-single-exe-for-a-wpf-ap for details.
    /// </remarks>
    public class Program
    {
        /// <summary>
        /// Entry point in for the single assembly
        /// </summary>
        [STAThreadAttribute]
        public static void Main()
        {
            AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
            App.Main();
        }

        /// <summary>
        /// Loads the assembly from the embedded resource on demand
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The <see cref="System.ResolveEventArgs"/> instance containing the event data.</param>
        /// <returns></returns>
        private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
        {
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            AssemblyName assemblyName = new AssemblyName(args.Name);

            string path = assemblyName.Name + ".dll";
            if (assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture) == false)
            {
                path = String.Format(@"{0}\{1}", assemblyName.CultureInfo, path);
            }

            using (Stream stream = executingAssembly.GetManifestResourceStream(path))
            {
                if (stream == null)
                    return null;

                byte[] assemblyRawBytes = new byte[stream.Length];
                stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length);
                return Assembly.Load(assemblyRawBytes);
            }
        }
    }
}
